/*
 * 大屏展示控制器
 * 提供WMS系统的统计数据用于大屏展示
 */
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VOL.Entity.DomainModels;
using VOL.Core.DBManager;
using SqlSugar;

namespace VOL.demo.Controllers
{
    [Route("api/Dashboard")]
    [ApiController]
    public class DashboardController : ControllerBase
    {
        private readonly ISqlSugarClient _db;

        public DashboardController()
        {
            _db = DBServerProvider.SqlSugarClient;
        }

        /// <summary>
        /// 获取大屏展示数据
        /// </summary>
        /// <returns>大屏展示数据</returns>
        [HttpGet("GetDashboardData")]
        public async Task<IActionResult> GetDashboardData()
        {
            try
            {
                var result = new DashboardDataDto
                {
                    TodayOverview = await GetOverviewData(DateTime.Today),
                    YesterdayOverview = await GetOverviewData(DateTime.Today.AddDays(-1)),
                    InventoryQuantityByWarehouse = await GetInventoryQuantityByWarehouse(),
                    InventoryAmountByWarehouse = await GetInventoryAmountByWarehouse()
                };

                // 计算总库存数量和金额
                result.TotalInventoryQuantity = result.InventoryQuantityByWarehouse.Sum(x => x.Quantity);
                result.TotalInventoryAmount = result.InventoryAmountByWarehouse.Sum(x => x.Amount);

                return Ok(new { success = true, data = result, message = "查询成功" });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取指定日期的概况数据
        /// </summary>
        /// <param name="date">日期</param>
        /// <returns>概况数据</returns>
        private async Task<DashboardOverviewDto> GetOverviewData(DateTime date)
        {
            var startDate = date.Date;
            var endDate = date.Date.AddDays(1);

            // 查询入库单据统计
            var inboundStats = await _db.Queryable<StockInOrderModel>()
                .LeftJoin<StockInOrderItemModel>((main, item) => main.stockInCode == item.StockInCode)
                .Where((main, item) => main.stockInDate >= startDate && main.stockInDate < endDate && (main.IsDel == 0 || main.IsDel == null))
                .Select((main, item) => new
                {
                    OrderId = main.Id,
                    Quantity = item.thisTimeQuantity ?? 0,
                    Amount = (decimal)(SqlFunc.IsNull(item.thisTimeQuantity, 0) * SqlFunc.IsNull(item.purchasePrice, 0))
                })
                .ToListAsync();

            // 查询出库单据统计
            var outboundStats = await _db.Queryable<outboundmodel>()
                .Where(x => x.CreateDate >= startDate && x.CreateDate < endDate && (x.IsDelete == 0 || x.IsDelete == null))
                .ToListAsync();

            var overview = new DashboardOverviewDto
            {
                // 单据数量 = 入库单数 + 出库单数
                OrderCount = inboundStats.Select(x => x.OrderId).Distinct().Count() + outboundStats.Count,
                
                // 入库统计
                InboundQuantity = inboundStats.Sum(x => x.Quantity),
                InboundAmount = inboundStats.Sum(x => x.Amount),
                
                // 出库统计
                OutboundQuantity = outboundStats.Sum(x => x.OutboundAllNum),
                OutboundAmount = outboundStats.Sum(x => x.OutboundAllMoney)
            };

            return overview;
        }

        /// <summary>
        /// 获取各仓库库存数量统计
        /// </summary>
        /// <returns>库存数量统计列表</returns>
        private async Task<List<WarehouseStatDto>> GetInventoryQuantityByWarehouse()
        {
            var stats = await _db.Queryable<InventoryModel>()
                .LeftJoin<warehousemodel>((inv, wh) => inv.WarehouseId == wh.Id)
                .Where((inv, wh) => (inv.IsDel == 0 || inv.IsDel == null) && (wh.IsDel == 0 || wh.IsDel == null))
                .GroupBy((inv, wh) => new { wh.Id, wh.WarehouseName })
                .Select((inv, wh) => new WarehouseStatDto
                {
                    WarehouseId = wh.Id,
                    WarehouseName = wh.WarehouseName,
                    Quantity = SqlFunc.AggregateSum(inv.CurrentQty),
                    Amount = 0
                })
                .ToListAsync();

            return stats;
        }

        /// <summary>
        /// 获取各仓库库存金额统计
        /// </summary>
        /// <returns>库存金额统计列表</returns>
        private async Task<List<WarehouseStatDto>> GetInventoryAmountByWarehouse()
        {
            // 这里需要连接货品表获取单价，简化处理直接使用仓库表中的库存金额字段
            var stats = await _db.Queryable<warehousemodel>()
                .Where(wh => wh.IsDel == 0 || wh.IsDel == null)
                .Select(wh => new WarehouseStatDto
                {
                    WarehouseId = wh.Id,
                    WarehouseName = wh.WarehouseName,
                    Quantity = wh.InventoryNum ?? 0,
                    Amount = wh.InventoryMomeny ?? 0
                })
                .ToListAsync();

            return stats;
        }

        /// <summary>
        /// 获取今日概况
        /// </summary>
        /// <returns>今日概况数据</returns>
        [HttpGet("GetTodayOverview")]
        public async Task<IActionResult> GetTodayOverview()
        {
            try
            {
                var data = await GetOverviewData(DateTime.Today);
                return Ok(new { success = true, data = data, message = "查询成功" });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取昨日概况
        /// </summary>
        /// <returns>昨日概况数据</returns>
        [HttpGet("GetYesterdayOverview")]
        public async Task<IActionResult> GetYesterdayOverview()
        {
            try
            {
                var data = await GetOverviewData(DateTime.Today.AddDays(-1));
                return Ok(new { success = true, data = data, message = "查询成功" });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取库存数量占比
        /// </summary>
        /// <returns>各仓库库存数量</returns>
        [HttpGet("GetInventoryQuantityStats")]
        public async Task<IActionResult> GetInventoryQuantityStats()
        {
            try
            {
                var data = await GetInventoryQuantityByWarehouse();
                var total = data.Sum(x => x.Quantity);
                
                return Ok(new
                {
                    success = true,
                    data = data,
                    total = total,
                    message = "查询成功"
                });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取库存金额占比
        /// </summary>
        /// <returns>各仓库库存金额</returns>
        [HttpGet("GetInventoryAmountStats")]
        public async Task<IActionResult> GetInventoryAmountStats()
        {
            try
            {
                var data = await GetInventoryAmountByWarehouse();
                var total = data.Sum(x => x.Amount);
                
                return Ok(new
                {
                    success = true,
                    data = data,
                    total = total,
                    message = "查询成功"
                });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取入库趋势统计
        /// </summary>
        /// <param name="days">统计天数，默认7天，可选：7、30、365</param>
        /// <returns>入库趋势数据</returns>
        [HttpGet("GetInboundTrendStats")]
        public async Task<IActionResult> GetInboundTrendStats(int days = 7)
        {
            try
            {
                var data = await GetInboundTrendData(days);
                
                return Ok(new
                {
                    success = true,
                    data = data,
                    message = "查询成功"
                });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取出库趋势统计
        /// </summary>
        /// <param name="days">统计天数，默认7天，可选：7、30、365</param>
        /// <returns>出库趋势数据</returns>
        [HttpGet("GetOutboundTrendStats")]
        public async Task<IActionResult> GetOutboundTrendStats(int days = 7)
        {
            try
            {
                var data = await GetOutboundTrendData(days);
                
                return Ok(new
                {
                    success = true,
                    data = data,
                    message = "查询成功"
                });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取入库趋势数据
        /// </summary>
        /// <param name="days">统计天数</param>
        /// <returns>趋势统计数据</returns>
        private async Task<TrendStatDto> GetInboundTrendData(int days)
        {
            var endDate = DateTime.Today.AddDays(1); // 包含今天
            var startDate = DateTime.Today.AddDays(-days + 1); // 往前推days天

            // 查询入库单据数据
            var inboundData = await _db.Queryable<StockInOrderModel>()
                .LeftJoin<StockInOrderItemModel>((main, item) => main.stockInCode == item.StockInCode)
                .Where((main, item) => 
                    main.stockInDate >= startDate && 
                    main.stockInDate < endDate && 
                    (main.IsDel == 0 || main.IsDel == null))
                .Select((main, item) => new
                {
                    Date = main.stockInDate,
                    Quantity = item.thisTimeQuantity ?? 0,
                    Amount = (decimal)(SqlFunc.IsNull(item.thisTimeQuantity, 0) * SqlFunc.IsNull(item.purchasePrice, 0))
                })
                .ToListAsync();

            // 按日期分组统计
            var dailyStats = new List<DailyStatDto>();
            for (int i = 0; i < days; i++)
            {
                var date = startDate.AddDays(i);
                var dateStr = date.ToString("yyyy-MM-dd");
                
                var dayData = inboundData.Where(x => 
                    x.Date.HasValue && 
                    x.Date.Value.Date == date.Date
                ).ToList();

                dailyStats.Add(new DailyStatDto
                {
                    Date = dateStr,
                    Quantity = dayData.Sum(x => x.Quantity),
                    Amount = dayData.Sum(x => x.Amount)
                });
            }

            // 构建返回结果
            var result = new TrendStatDto
            {
                Dates = dailyStats.Select(x => x.Date).ToList(),
                Quantities = dailyStats.Select(x => x.Quantity).ToList(),
                Amounts = dailyStats.Select(x => x.Amount).ToList(),
                TotalQuantity = dailyStats.Sum(x => x.Quantity),
                TotalAmount = dailyStats.Sum(x => x.Amount)
            };

            return result;
        }

        /// <summary>
        /// 获取出库趋势数据
        /// </summary>
        /// <param name="days">统计天数</param>
        /// <returns>趋势统计数据</returns>
        private async Task<TrendStatDto> GetOutboundTrendData(int days)
        {
            var endDate = DateTime.Today.AddDays(1); // 包含今天
            var startDate = DateTime.Today.AddDays(-days + 1); // 往前推days天

            // 查询出库单据数据（按创建日期统计）
            var outboundData = await _db.Queryable<outboundmodel>()
                .Where(x => 
                    x.CreateDate >= startDate && 
                    x.CreateDate < endDate && 
                    (x.IsDelete == 0 || x.IsDelete == null))
                .Select(x => new
                {
                    Date = x.CreateDate,
                    Quantity = x.OutboundAllNum,
                    Amount = x.OutboundAllMoney
                })
                .ToListAsync();

            // 按日期分组统计
            var dailyStats = new List<DailyStatDto>();
            for (int i = 0; i < days; i++)
            {
                var date = startDate.AddDays(i);
                var dateStr = date.ToString("yyyy-MM-dd");
                
                var dayData = outboundData.Where(x => 
                    x.Date.HasValue && 
                    x.Date.Value.Date == date.Date
                ).ToList();

                dailyStats.Add(new DailyStatDto
                {
                    Date = dateStr,
                    Quantity = dayData.Sum(x => x.Quantity),
                    Amount = dayData.Sum(x => x.Amount)
                });
            }

            // 构建返回结果
            var result = new TrendStatDto
            {
                Dates = dailyStats.Select(x => x.Date).ToList(),
                Quantities = dailyStats.Select(x => x.Quantity).ToList(),
                Amounts = dailyStats.Select(x => x.Amount).ToList(),
                TotalQuantity = dailyStats.Sum(x => x.Quantity),
                TotalAmount = dailyStats.Sum(x => x.Amount)
            };

            return result;
        }

        /// <summary>
        /// 获取入库排名
        /// </summary>
        /// <param name="topN">显示前N名，默认10</param>
        /// <param name="days">统计天数，默认30天</param>
        /// <returns>入库排名列表</returns>
        [HttpGet("GetInboundRanking")]
        public async Task<IActionResult> GetInboundRanking(int topN = 10, int days = 30)
        {
            try
            {
                var data = await GetInboundRankingData(topN, days);
                
                return Ok(new
                {
                    success = true,
                    data = data,
                    message = "查询成功"
                });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取出库排名
        /// </summary>
        /// <param name="topN">显示前N名，默认10</param>
        /// <param name="days">统计天数，默认30天</param>
        /// <returns>出库排名列表</returns>
        [HttpGet("GetOutboundRanking")]
        public async Task<IActionResult> GetOutboundRanking(int topN = 10, int days = 30)
        {
            try
            {
                var data = await GetOutboundRankingData(topN, days);
                
                return Ok(new
                {
                    success = true,
                    data = data,
                    message = "查询成功"
                });
            }
            catch (Exception ex)
            {
                return Ok(new { success = false, message = $"查询失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取入库排名数据
        /// </summary>
        /// <param name="topN">显示前N名</param>
        /// <param name="days">统计天数</param>
        /// <returns>排名列表</returns>
        private async Task<List<GoodsRankDto>> GetInboundRankingData(int topN, int days)
        {
            var endDate = DateTime.Today.AddDays(1);
            var startDate = DateTime.Today.AddDays(-days + 1);

            // 查询入库数据，按货品分组统计
            var rankingData = await _db.Queryable<StockInOrderModel>()
                .LeftJoin<StockInOrderItemModel>((main, item) => main.stockInCode == item.StockInCode)
                .Where((main, item) => 
                    main.stockInDate >= startDate && 
                    main.stockInDate < endDate && 
                    (main.IsDel == 0 || main.IsDel == null) &&
                    (item.IsDel == 0 || item.IsDel == null) &&  // 过滤明细表的删除标识
                    !string.IsNullOrEmpty(item.StockInCode) &&   // 确保入库单号不为空
                    item.GoodsId > 0)                             // 确保货品ID有效
                .GroupBy((main, item) => new { item.GoodsId, item.GoodsName })
                .Select((main, item) => new
                {
                    GoodsId = item.GoodsId,
                    GoodsName = item.GoodsName,
                    TotalQuantity = SqlFunc.AggregateSum(item.thisTimeQuantity),
                    TotalAmount = SqlFunc.AggregateSum(SqlFunc.IsNull(item.thisTimeQuantity, 0) * SqlFunc.IsNull(item.purchasePrice, 0)),
                    InboundCount = SqlFunc.AggregateCount(item.Id)
                })
                .MergeTable() // 合并表后再排序
                .OrderBy(x => x.TotalQuantity, OrderByType.Desc) // 按数量降序排序
                .Take(topN)
                .ToListAsync();

            // 添加排名
            var result = rankingData.Select((item, index) => new GoodsRankDto
            {
                Rank = index + 1,
                GoodsId = item.GoodsId,
                GoodsName = item.GoodsName ?? "未知货品",
                Quantity = item.TotalQuantity ?? 0,
                Amount = item.TotalAmount ?? 0,
                Count = item.InboundCount
            }).ToList();

            return result;
        }

        /// <summary>
        /// 获取出库排名数据
        /// </summary>
        /// <param name="topN">显示前N名</param>
        /// <param name="days">统计天数</param>
        /// <returns>排名列表</returns>
        private async Task<List<GoodsRankDto>> GetOutboundRankingData(int topN, int days)
        {
            var endDate = DateTime.Today.AddDays(1);
            var startDate = DateTime.Today.AddDays(-days + 1);

            // 由于出库表结构，这里使用简化的查询
            // 实际项目中可能需要关联具体的货品明细表
            // 这里先返回按出库单汇总的数据作为示例
            
            // 如果有出库明细表关联货品信息，可以类似入库的方式查询
            // 由于outbounddetailmodel没有货品信息，这里使用出库单主表的数据
            var rankingData = await _db.Queryable<outboundmodel>()
                .Where(x => 
                    x.CreateDate >= startDate && 
                    x.CreateDate < endDate && 
                    (x.IsDelete == 0 || x.IsDelete == null))
                .GroupBy(x => x.OutboundAllGoods) // 按货品字段分组（如果有的话）
                .Select(x => new
                {
                    GoodsName = x.OutboundAllGoods,
                    TotalQuantity = SqlFunc.AggregateSum(x.OutboundAllNum),
                    TotalAmount = SqlFunc.AggregateSum(x.OutboundAllMoney),
                    OutboundCount = SqlFunc.AggregateCount(x.Id)
                })
                .OrderBy(x => x.TotalQuantity, OrderByType.Desc)
                .Take(topN)
                .ToListAsync();

            // 添加排名
            var result = rankingData.Select((item, index) => new GoodsRankDto
            {
                Rank = index + 1,
                GoodsId = 0, // 如果没有货品ID，设为0
                GoodsName = item.GoodsName ?? "未知货品",
                Quantity = item.TotalQuantity,
                Amount = item.TotalAmount,
                Count = item.OutboundCount
            }).ToList();

            return result;
        }
    }
}

